<!DOCTYPE html>
<html><head><title>Pathy</title>
  <script src="lightgl/lightgl.js"></script>
  <script>
      function script(id) {
          var shaderScript = document.getElementById(id);
          if(!shaderScript)
              return null;

          var str = '';
          var childNode = shaderScript.firstChild;
          while(childNode) {
              if(childNode.nodeType == 3) {
                  str += childNode.textContent;
              }
              childNode = childNode.nextSibling;
          }
          return str;
      }
  </script>
  <script id="rainbow-vs" type="x-shader/x-vertex">
      varying vec3 normal;
      void main() {
        normal = gl_Normal;
        gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
      }
  </script>
  <script id="rainbow-fs" type="x-shader/x-fragment">
      uniform float brightness;
      varying vec3 normal;
      void main() {
        gl_FragColor = vec4(brightness * (normal * 0.5 + 0.5), 1.0);
      }
  </script>
  <script id="checker-vs" type="x-shader/x-vertex">
      varying highp vec2 vTextureCoord;
      void main() {
        vTextureCoord = vec2(gl_TexCoord);
        gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
      }
  </script>
  <script id="checker-fs" type="x-shader/x-fragment">
      varying highp vec2 vTextureCoord;
      void main() {
        float col = mod(floor(vTextureCoord.s*10.0) + floor(vTextureCoord.t*10.0),2.0);
        vec3 base = vec3(1.0, 0.0, 0.0);
        gl_FragColor = vec4(col * base, 1.0);
      }
  </script>
  <script id="viewbox-vs" type="x-shader/x-vertex">
        uniform vec3 eye;
        uniform vec3 ray00;
        uniform vec3 ray01;
        uniform vec3 ray10;
        uniform vec3 ray11;

      void main() {
    
        vec3 ray0 = ray00 + gl_Vertex.x * (ray10 - ray00);
        vec3 ray1 = ray01 + gl_Vertex.x * (ray11 - ray01);
        vec3 ray = ray0 + gl_Vertex.y * (ray1 - ray0);

          vec3 vertex = eye - ray * (eye.z / ray.z);

          vertex.z = 1.0;

        gl_Position = gl_ModelViewProjectionMatrix * vec4(vertex, 1.0);
      }
  </script>
  <script id="viewbox-fs" type="x-shader/x-fragment">
      void main() {
        gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0);
      }
  </script>
  <script>
var angleX = -35;
var angleY = 45;
var gl = GL.create();
var camera = new GL.Vector(5, 5, 5);
var mesh = GL.Mesh.sphere({ normals: true, radius: 4 }).computeWireframe();
var ground = GL.Mesh.plane({ coords: true, detail: 5 }).transform(GL.Matrix.scale(10, 10, 0));
var square = GL.Mesh.plane({ coords: true, detail: 1 }).transform(GL.Matrix.scale(0.5, 0.5, 1.0).multiply(GL.Matrix.translate(1.0, 1.0, 0.0)));
var rainbow = new GL.Shader(script('rainbow-vs'), script('rainbow-fs'));
var checker = new GL.Shader(script('checker-vs'), script('checker-fs'));
var viewbox = new GL.Shader(script('viewbox-vs'), script('viewbox-fs'));

gl.onmousemove = function(e) {
  if (e.dragging) {
    var w = gl.canvas.width;
    var h = gl.canvas.height;
  var mini = Math.max(w, h)/10
      if(e.x < mini && (h - e.y) < mini) {
        var x = (e.x / mini)*20-10;
        var y = ((h - e.y) / mini)*20-10;

        camera.x = x;
        camera.y = y;
      } else {
    angleY -= e.deltaX * 0.25;
    angleX = Math.max(-90, Math.min(90, angleX - e.deltaY * 0.25));
      }
  }
};

gl.onupdate = function(seconds) {
  var speed = seconds * 4;

  // Forward movement
  var up = GL.keys.W | GL.keys.UP;
  var down = GL.keys.S | GL.keys.DOWN;
  var forward = GL.Vector.fromAngles((90 - angleY) * Math.PI / 180, (180 - angleX) * Math.PI / 180);
  camera = camera.add(forward.multiply(speed * (up - down)));

  // Sideways movement
  var left = GL.keys.A | GL.keys.LEFT;
  var right = GL.keys.D | GL.keys.RIGHT;
  var sideways = GL.Vector.fromAngles(-angleY * Math.PI / 180, 0);
  camera = camera.add(sideways.multiply(speed * (right - left)));
};

gl.ondraw = function() {
    var w = gl.canvas.width;
    var h = gl.canvas.height;
  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
  gl.viewport(0, 0, w, h);
        gl.matrixMode(gl.PROJECTION);
        gl.loadIdentity();
        gl.perspective(45, w / h, 0.1, 1000);
        gl.matrixMode(gl.MODELVIEW);
  gl.loadIdentity();
  gl.rotate(-angleX, 1, 0, 0);
  gl.rotate(-angleY, 0, 1, 0);
  gl.translate(-camera.x, -camera.y, -camera.z);

  rainbow.uniforms({ brightness: 1 }).draw(mesh, gl.TRIANGLES);
  rainbow.uniforms({ brightness: 0 }).draw(mesh, gl.LINES);
  checker.draw(ground, gl.TRIANGLES);

  var tracer = new GL.Raytracer();
  var pos;


  var mini = Math.max(w, h)/10
  gl.viewport(0, 0, mini, mini);
  gl.clear(gl.DEPTH_BUFFER_BIT);
        gl.matrixMode(gl.PROJECTION);
        gl.loadIdentity();
        gl.ortho(-10, 10, -10, 10, -10, 10);
        gl.matrixMode(gl.MODELVIEW);
  gl.loadIdentity();
  checker.draw(ground, gl.TRIANGLES);
  viewbox.uniforms({eye: tracer.eye, ray00: tracer.ray00, ray01: tracer.ray01, ray10: tracer.ray10, ray11: tracer.ray11}).draw(square, gl.TRIANGLES);
};

function setup() {
gl.fullscreen();
gl.animate();
gl.enable(gl.CULL_FACE);
gl.enable(gl.POLYGON_OFFSET_FILL);
gl.polygonOffset(1, 1);
gl.clearColor(0.8, 0.8, 0.8, 1);
gl.enable(gl.DEPTH_TEST);
}

  </script>  </head>

<body onload="setup()"></body></html>